/*
 * Copyright 2006-2023 ahtelit.com, All Rights Reserved.
 */

package com.telit.firecommand.util;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.telit.common.constant.Constant;
import com.telit.common.entity.PageData;
import com.telit.common.exception.ForestBaseException;
import com.telit.common.util.Md5Util;
import com.telit.common.util.RedisUtils;
import com.telit.common.util.WebUtils;
import com.telit.firecommand.config.properties.EquipStationProperties;
import com.telit.firecommand.constant.RedisKeyConstant;
import com.telit.firecommand.entity.SciMeteoricData;
import com.telit.firecommand.entity.SciWaterQualityData;
import com.telit.firecommand.entity.SysEquipStation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 物联网设备
 *
 * @author yuezhuang
 * @since 2023-04-01
 */
@Slf4j
public class EquipStationUtils {

    private static String API_URL;
    private static String LOGIN_NAME;
    private static String LOGIN_PASSWORD;

    public static final String GET_ACCESS_TOKEN_URI = "/mq-mgt-system/home/login";
    public static final String GET_EQUIP_STATION_PAGE_URI = "/mq-mgt-system/equip/station/page";//设备列表
    public static final String GET_RAIN_PAGE_URI = "/mq-mgt-scientific/rain/selectPage";//气象站数据
    public static final String GET_WATER_QUALITY_PAGE_URI = "/mq-mgt-scientific/waterQuality/selectPage";//水文数据

    private static final Map<String, String> HEADERS = new HashMap<>();

    static {
        HEADERS.put("Content-Type", "application/json");
    }

    /**
     * 初始化配置信息
     *
     * @param equipStationProperties 配置信息
     */
    public static void init(EquipStationProperties equipStationProperties) {
        API_URL = equipStationProperties.getApiUrl();
        LOGIN_NAME = equipStationProperties.getLoginName();
        LOGIN_PASSWORD = equipStationProperties.getLoginPassword();
    }

    /**
     * 获取 access_token
     *
     * @return access_token
     */
    private static String getAccessToken() {
        String accessToken = RedisUtils.get(RedisKeyConstant.EQUIP_STATION_ACCESS_TOKEN);
        if (StringUtils.isNotEmpty(accessToken)) {
            return accessToken;
        }

        Map<String, String> requestParams = new HashMap<>();
        requestParams.put("clientType", "1");
        requestParams.put("username", LOGIN_NAME);
        requestParams.put("password", Md5Util.stringMD5(LOGIN_PASSWORD));
        Map<String, Object> dataMap = callRequest(GET_ACCESS_TOKEN_URI, null, Constant.REQUEST_METHOD_POST,
                requestParams);
        accessToken = MapUtil.getStr(dataMap, "token");
        RedisUtils.set(RedisKeyConstant.EQUIP_STATION_ACCESS_TOKEN, accessToken,
                RedisKeyConstant.EQUIP_STATION_ACCESS_TOKEN_EXPIRE_TIME);
        return accessToken;
    }

    /**
     * 查询设备列表
     *
     * @param pageIndex 当前页数
     * @param pageSize  每页条数
     * @param type      监测站类型（1:气象站，2:水文站）
     *
     * @return SysEquipStation
     */
    public static PageData<List<SysEquipStation>> getEquipStationList(Integer pageIndex, Integer pageSize,
                                                                      Integer type) {
        Map<String, String> requestParams = new HashMap<>();
        requestParams.put("pageIndex", pageIndex.toString());
        requestParams.put("pageSize", pageSize.toString());
        if (type != null) {
            requestParams.put("type", type.toString());
        }

        Map<String, Object> dataMap = callRequest(GET_EQUIP_STATION_PAGE_URI, getAccessToken(),
                Constant.REQUEST_METHOD_GET, requestParams);
        List<SysEquipStation> values = JSON.parseArray(MapUtil.getStr(dataMap, "records"), SysEquipStation.class);
        int total = MapUtil.getInt(dataMap, "total");

        return PageData.<List<SysEquipStation>>builder()
                .count(total)
                .current(pageIndex)
                .size(pageSize)
                .datas(values)
                .build();
    }

    /**
     * 查询水文数据
     *
     * @param pageIndex 当前页数
     * @param pageSize  每页条数
     * @param code      设备编码
     * @param endTime   结束时间
     * @param startTime 开始时间
     *
     * @return SciWaterQualityData
     */
    public static PageData<List<SciWaterQualityData>> getWaterQualityList(Integer pageIndex, Integer pageSize,
                                                                          String code, String startTime,
                                                                          String endTime) {
        Map<String, String> requestParams = new HashMap<>();
        requestParams.put("pageIndex", pageIndex.toString());
        requestParams.put("pageSize", pageSize.toString());
        requestParams.put("code", code);
        requestParams.put("endTime", endTime);
        requestParams.put("startTime", startTime);

        Map<String, Object> dataMap = callRequest(GET_WATER_QUALITY_PAGE_URI, getAccessToken(),
                Constant.REQUEST_METHOD_POST, requestParams);
        List<SciWaterQualityData> values = JSON.parseArray(MapUtil.getStr(dataMap, "records"),
                SciWaterQualityData.class);
        int total = MapUtil.getInt(dataMap, "total");

        return PageData.<List<SciWaterQualityData>>builder()
                .count(total)
                .current(pageIndex)
                .size(pageSize)
                .datas(values)
                .build();
    }

    /**
     * 查询气象数据
     *
     * @param pageIndex 当前页数
     * @param pageSize  每页条数
     * @param code      设备编码
     * @param endTime   结束时间
     * @param startTime 开始时间
     *
     * @return SciMeteoricData
     */
    public static PageData<List<SciMeteoricData>> getRainList(Integer pageIndex, Integer pageSize,
                                                              String code, String startTime, String endTime) {
        Map<String, String> requestParams = new HashMap<>();
        requestParams.put("pageIndex", pageIndex.toString());
        requestParams.put("pageSize", pageSize.toString());
        requestParams.put("code", code);
        requestParams.put("endTime", endTime);
        requestParams.put("startTime", startTime);

        Map<String, Object> dataMap = callRequest(GET_RAIN_PAGE_URI, getAccessToken(),
                Constant.REQUEST_METHOD_POST, requestParams);
        List<SciMeteoricData> values = JSON.parseArray(MapUtil.getStr(dataMap, "records"),
                SciMeteoricData.class);
        int total = MapUtil.getInt(dataMap, "total");

        return PageData.<List<SciMeteoricData>>builder()
                .count(total)
                .current(pageIndex)
                .size(pageSize)
                .datas(values)
                .build();
    }

    /**
     * http请求
     *
     * @param url           请求地址
     * @param requestParams 请求参数
     *
     * @return http请求结果
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> callRequest(String url, String token, String method,
                                                  Map<String, String> requestParams) {
        try {
            if (StrUtil.isNotEmpty(token)) {
                HEADERS.put("authc-token", token);
            }

            log.info("物联网设备系统，接口地址：{}， 请求参数：{}", API_URL + url, JSON.toJSONString(requestParams));
            String result = null;
            if (Constant.REQUEST_METHOD_GET.equals(method)) {
                result = WebUtils.doGetWithRequestParameters(API_URL + url, HEADERS, requestParams);
            } else if (Constant.REQUEST_METHOD_POST.equals(method)) {
                result = WebUtils.doPostWithRequestBody(true, API_URL + url, JSON.toJSONString(requestParams), HEADERS,
                        0, 0);
            }
            log.info("物联网设备系统，返回结果：{}", result);

            Map<String, Object> resultMap = JSON.parseObject(result, Map.class);
            Validate.isTrue(MapUtil.getInt(resultMap, "code") == 20000);
            String data = MapUtil.getStr(resultMap, "data");
            return JSON.parseObject(data, Map.class);
        } catch (Exception e) {
            log.error("物联网设备系统，调用失败：{}", e.getMessage());

            throw new ForestBaseException("物联网设备系统，调用失败：" + e.getMessage());
        }
    }

}
